
/*
 * @deprecated This package is deprecated. Please use another one instead.
 */
package com.wlyuan.index.domain.index.valueobj;

import cn.hutool.core.util.ReflectUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @author yuanjie
 * 结算情况
 * 财务系统设计为发货方付款后，将bit位1置1，承运方收货将bit位2置1
 * 结账信息
 * Settlements
 */
@Data
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
@Deprecated
public class Balances {
    public static final Integer SETTLED = 1;
    private static final Integer IN = 1;
    private static final Integer OUT = 2;

    public static final String PREPAY = "prepayFee";
    public static final String ARRIVE_PAY = "arrivePayFee";
    public static final String COLLECTION = "collectionFee";
    public static final String RECEIPT = "receiptFee";
    public static final String OVERALL = "overallFee";

    private static final List<String> NAMES = Arrays.asList(PREPAY, ARRIVE_PAY, COLLECTION, RECEIPT, OVERALL);

    @Field(type = FieldType.Integer)
    private Integer prepayFee;
    @Field(type = FieldType.Integer)
    private Integer collectionFee;
    @Field(type = FieldType.Integer)
    private Integer arrivePayFee;
    @Field(type = FieldType.Integer)
    private Integer receiptFee;
    @Field(type = FieldType.Integer)
    private Integer overallFee;

    public void add(String name, Integer status) {
        if (!NAMES.contains(name)) {
            logger.error("Balance name not supported: {} {}", name, status);
            return;
        }
        ReflectUtil.setFieldValue(this, name, status);
    }

    public BigDecimal getSettledFee(String name, BigDecimal money) {
        return Optional.ofNullable(ReflectUtil.getFieldValue(this, name))
                .filter(status -> status instanceof Integer)
                .map(status -> (Integer) status)
                .filter(status -> status == 1)
                .map(status -> money)
                .orElse(BigDecimal.ZERO);
    }

    public boolean has(String name, boolean defaultValue) {
        return Optional.ofNullable(ReflectUtil.getFieldValue(this, name))
                .filter(status -> status instanceof Integer)
                .map(status -> (Integer) status)
                .map(status -> status != 1)
                .orElse(defaultValue);
    }

    public Integer split(String name, Integer character) {
        return Optional.ofNullable(ReflectUtil.getFieldValue(this, name))
                .filter(status -> status instanceof Integer)
                .map(status -> (Integer) status)
                .map(status -> {
                    // 发货方应付 承运方应收
                    var bit = Characters.CUSTOMER.equals(character) ? OUT : IN;
                    return (bit & status) == bit ? 1 : 0;
                })
                .orElse(null);
    }

    public static Balances split(Balances source, Integer character) {
        if (null == source) {
            return null;
        }

        var prepayFee = source.split(PREPAY, character);
        var arrivePayFee = source.split(ARRIVE_PAY, character);
        var collectionFee = source.split(COLLECTION, character);
        var receiptFee = source.split(RECEIPT, character);
        var overallFee = source.split(OVERALL, character);

        return new Balances(prepayFee, arrivePayFee, collectionFee, receiptFee, overallFee);
    }

    public static boolean settled(Integer status) {
        return SETTLED.equals(status);
    }
}
